package com.lzh.gulimall.order.service.impl;

import com.lzh.gulimall.order.entity.OrderEntity;
import com.lzh.gulimall.order.entity.OrderReturnReasonEntity;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzh.common.utils.PageUtils;
import com.lzh.common.utils.Query;

import com.lzh.gulimall.order.dao.OrderItemDao;
import com.lzh.gulimall.order.entity.OrderItemEntity;
import com.lzh.gulimall.order.service.OrderItemService;

/**
 * 监听hello-java-queue队列
 */
@RabbitListener(queues = {"hello-java-queue"})
@Service("orderItemService")
public class OrderItemServiceImpl extends ServiceImpl<OrderItemDao, OrderItemEntity> implements OrderItemService {

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<OrderItemEntity> page = this.page(
                new Query<OrderItemEntity>().getPage(params),
                new QueryWrapper<OrderItemEntity>()
        );

        return new PageUtils(page);
    }

    /**
     *
     * @RabbitListener：可以标在类和方法上
     * 属性queues:需要监听的所有队列
     *
     * 入参自动接受监听到的消息。
     * 类型为：org.springframework.amqp.core.Message
     *
     * 参数可以写以下类型：
     *      1.Message:原生消息详细信息
     *          message.getBody()获取消息体
     *          message.getMessageProperties()获取消息头
     *      2.T<发送的消息的类型> OrderEntity orderEntity
     *          入参写消息的类型，监听到消息时，消息自动封装到入参中，就可以不需要使用原生Message.getBody()去获取消息了
     *      3.Channel chanhel:当前传输数据的通道
     *Queue: 可以很多服务来监听。只要收到消息，队列就删除消息，而且只能有一个收到此消息
     * 场景：
     *      1.订单服务启动多个，监听同一个队列，队列里的消息，只能被一个订单的服务消息。一个消息，只能被一个客户端收到。
     *      2.只有一个消息完全处理完，方法执行完，才能去接受下一个消息。

     */
    /**
     * 获取队列里OrderEntity类型的消息
     * @param orderEntity
     */
    @RabbitHandler
    public void recieveMessage( OrderEntity orderEntity){

        System.out.println("内容OrderEntity："+orderEntity);
    }
    /**
     * 获取队列里OrderReturnReasonEntity类型的消息
     * @param orderReturnReasonEntity
     */
    @RabbitHandler
    public void recieveMessage(Message message,OrderReturnReasonEntity orderReturnReasonEntity,Channel channel)  {
        System.out.println("内容OrderReturnReasonEntity：" + orderReturnReasonEntity);

        //消息的标签
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        System.out.println("deliveryTag==>" + deliveryTag);
        try {
            if (deliveryTag%2==0) {
                //参数二：是否批量签收消息。 false：只回复当前消息已经处理完的ack给服务端
                channel.basicAck(deliveryTag, false);
                System.out.println("签收消息..."+deliveryTag);
            }else {
                /**
                 * 拒绝签收消息
                 * 参数三：requeue=false丢弃消息；requeue=true将消息发回服务器，重新入队。入队后，在
                 * 参数二：是否批量拒绝，false只拒绝当前消息
                 * 参数一: 当前消息的tag
                 */
                channel.basicNack(deliveryTag,false,true);
                //同上，只不过少了一个参数
                //channel.basicReject();
                System.out.println("没有签收消息..."+deliveryTag);
            }
        }catch (Exception e){
            log.error("网络中断！");
        }
    }
}